/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       ownable_event.h

	$Header: /game/ownable_event.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( OWNABLE_EVENT_H_INCLUDED )
#define OWNABLE_EVENT_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <bitset>

#include "continuous_event.h"
#include "discrete_event.h"
#include "player_color.h"
#include "timed_event.h"
#include "triggerable_event.h"

// --------------------------------------------------------------------------
// t_ownable_event class
// --------------------------------------------------------------------------

class t_player;

class t_ownable_event
{
public:
	// Types
	typedef std::bitset< k_player_color_count >	t_owner_color_mask;

	// Member functions
	t_owner_color_mask const &	get_owner_color_mask() const;
	bool						get_run_for_computer_owners() const;
	bool						get_run_for_human_owners() const;
	bool						ownership_test(t_player const* player) const;

protected:
	// Constructors/Destructor
	t_ownable_event();
	t_ownable_event( t_ownable_event const & other );
	~t_ownable_event() {}

	// Member functions
	bool	read(
				std::streambuf &	stream,
				int					version );
	bool	read_from_map(
				std::streambuf &	stream,
				int					format_version );
	bool	write( std::streambuf & stream ) const;

	// Operators
	t_ownable_event &	operator=( t_ownable_event const & other );

private:
	// Data members
	t_owner_color_mask	m_owner_color_mask;
	bool				m_run_for_human_owners;
	bool				m_run_for_computer_owners;
};

// --------------------------------------------------------------------------
// t_ownable_event inline members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline t_ownable_event::t_owner_color_mask const &
t_ownable_event::get_owner_color_mask() const
{
	return m_owner_color_mask;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline bool t_ownable_event::get_run_for_computer_owners() const
{
	return m_run_for_computer_owners;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline bool t_ownable_event::get_run_for_human_owners() const
{
	return m_run_for_human_owners;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline t_ownable_event::t_ownable_event()
	:	m_run_for_human_owners( true ),
		m_run_for_computer_owners( true )
{
	m_owner_color_mask.set();
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline t_ownable_event::t_ownable_event( t_ownable_event const & other )
	:	m_owner_color_mask( other.m_owner_color_mask ),
		m_run_for_human_owners( other.m_run_for_human_owners ),
		m_run_for_computer_owners( other.m_run_for_computer_owners )
{
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline t_ownable_event & t_ownable_event::operator=(
	t_ownable_event const &	other )
{
	m_owner_color_mask = other.m_owner_color_mask;
	m_run_for_human_owners = other.m_run_for_human_owners;
	m_run_for_computer_owners = other.m_run_for_computer_owners;

	return *this;
}

// --------------------------------------------------------------------------
// t_ownable_built_in_event class
// --------------------------------------------------------------------------

class t_ownable_built_in_event
	:	public t_discrete_event,
		public t_ownable_event
{
public:
	// Member functions
	bool	read( std::streambuf & stream, int version );
	bool	read_from_map( std::streambuf & stream );
	bool	write( std::streambuf & stream ) const;
};

// --------------------------------------------------------------------------
// t_ownable_built_in_event inline members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline bool t_ownable_built_in_event::read(
	std::streambuf &	stream,
	int					version )
{
	return		t_discrete_event::read( stream, version )
			&&	t_ownable_event::read( stream, version );
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline bool t_ownable_built_in_event::write( std::streambuf & stream ) const
{
	return		t_discrete_event::write( stream )
			&&	t_ownable_event::write( stream );
}

// --------------------------------------------------------------------------
// t_ownable_timed_event class
// --------------------------------------------------------------------------

class t_ownable_timed_event
	:	public t_timed_event,
		public t_ownable_event
{
public:
	// Constructor
	t_ownable_timed_event();

	// Member functions
	void	clear_execution_flag();
	bool	has_executed() const;
	bool	read( std::streambuf & stream, int version );
	bool	read_from_map( std::streambuf & stream );
	void	set_execution_flag();
	bool	write( std::streambuf & stream ) const;

private:
	// Data members
	bool	m_execution_flag;
};

// --------------------------------------------------------------------------
// t_ownable_timed_event inline members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline t_ownable_timed_event::t_ownable_timed_event()
	:	m_execution_flag( false )
{
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline void t_ownable_timed_event::clear_execution_flag()
{
	m_execution_flag = false;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline bool t_ownable_timed_event::has_executed() const
{
	return m_execution_flag;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline void t_ownable_timed_event::set_execution_flag()
{
	m_execution_flag = true;
}

// --------------------------------------------------------------------------
// t_ownable_triggerable_event class
// --------------------------------------------------------------------------

class t_ownable_triggerable_event
	:	public t_triggerable_event,
		public t_ownable_event
{
public:
	// Member functions
	bool	read( std::streambuf & stream, int version );
	bool	read_from_map( std::streambuf & stream );
	bool	write( std::streambuf & stream ) const;
};

// --------------------------------------------------------------------------
// t_ownable_triggerable_event inline members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline bool t_ownable_triggerable_event::read(
	std::streambuf &	stream,
	int					version )
{
	return		t_triggerable_event::read( stream, version )
			&&	t_ownable_event::read( stream, version );
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline bool t_ownable_triggerable_event::write(
	std::streambuf &	stream ) const
{
	return		t_triggerable_event::write( stream )
			&&	t_ownable_event::write( stream );
}

// --------------------------------------------------------------------------
// t_ownable_continuous_event class
// --------------------------------------------------------------------------

class t_ownable_continuous_event
	:	public t_continuous_event,
		public t_ownable_event
{
public:
	// Constructor
	t_ownable_continuous_event();

	// Member functions
	bool	get_run_only_during_owners_turn() const;
	bool	read( std::streambuf & stream, int version );
	bool	read_from_map( std::streambuf & stream );
	void	set_run_only_during_owners_turn( bool new_flag );
	bool	write( std::streambuf & stream ) const;

private:
	// Data members
	bool	m_run_only_during_owners_turn;
};

// --------------------------------------------------------------------------
// t_ownable_continuous_event inline members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline t_ownable_continuous_event::t_ownable_continuous_event()
	:	m_run_only_during_owners_turn( true )
{
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline bool t_ownable_continuous_event::get_run_only_during_owners_turn() const
{
	return m_run_only_during_owners_turn;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline void t_ownable_continuous_event::set_run_only_during_owners_turn(
	bool	new_flag )
{
	m_run_only_during_owners_turn = new_flag;
}

#endif // !defined( OWNABLE_EVENT_H_INCLUDED )
